package com.ruoyi.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.ruoyi.domain.UserHealthData;
import com.ruoyi.mapper.UserHealthDataMapper;
import com.ruoyi.service.UserHealthDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

@Service
public class UserHealthDataServiceImpl implements UserHealthDataService {
    private final RestTemplate restTemplate;
    private final UserHealthDataMapper dataMapper;

    private static final String API_KEY = "5e59b58cfdcb8461b921615878224f96";
    private static final String API_URL = "http://nihao.relang.tv/index/Openapi/health_data";
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private static final Map<Integer, String> TYPE_MAPPING = new HashMap<>();
    static {
        TYPE_MAPPING.put(0, "heart_rate");
        TYPE_MAPPING.put(1, "blood_pressure");
        TYPE_MAPPING.put(2, "blood_oxygen");
        TYPE_MAPPING.put(3, "temperature");
        TYPE_MAPPING.put(4, "blood_glucose");
    }

    @Autowired
    public UserHealthDataServiceImpl(RestTemplate restTemplate, UserHealthDataMapper dataMapper) {
        this.restTemplate = restTemplate;
        this.dataMapper = dataMapper;
    }

    @Retryable()
    @Override
    public void fetchAndSaveData(int dataType) {
        try {
            int currentPage = 1;
            boolean hasMore = true;

            while (hasMore) {
                String url = buildRequestUrl(dataType, currentPage);
                JsonNode response = restTemplate.getForObject(url, JsonNode.class);

                if (response != null && response.get("code").asInt() == 200) {
                    Long userId = response.get("user_id").asLong(); // 从根节点获取user_id
                    JsonNode list = response.get("data").get("list");
                    processDataList(list, dataType, userId);

                    // 处理分页
                    JsonNode pagination = response.get("data").get("pagination");
                    int lastPage = pagination.get("last_page").asInt();
                    hasMore = currentPage < lastPage;
                    currentPage++;
                } else {
                    hasMore = false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private String buildRequestUrl(int dataType, int page) {
        return String.format("%s?key=%s&type=%d&page=%d", API_URL, API_KEY, dataType, page);
    }

    private void processDataList(JsonNode list, int dataType, Long userId) {
        list.forEach(item -> {
            UserHealthData data = parseData(item, dataType, userId);
            if (data != null && !isDataExists(data, dataType)) {
                dataMapper.insertData(data, TYPE_MAPPING.get(dataType));
            }
        });
    }

    private UserHealthData parseData(JsonNode item, int dataType, Long userId) {
        try {
            UserHealthData data = new UserHealthData();
            data.setUserId(userId); // 使用根节点的userId

            // 将API返回的时间字符串转为数据库兼容格式
            String timeStr = item.get("time").asText();
            DateTimeFormatter dbFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime dbTime = LocalDateTime.parse(timeStr, dbFormatter);
            data.setTime(dbTime);

            switch (dataType) {
                case 0:  // 心率
                    data.setHeartRate(item.get("rateValue").asInt());
                    break;
                case 1:  // 血压
                    data.setBloodPressureHigh(item.get("HighValue").asInt());
                    data.setBloodPressureLow(item.get("LowValue").asInt());
                    break;
                case 2:  // 血氧
                    data.setBloodOxygen(item.get("oxygens").asInt());
                    break;
                case 3:  // 体温
                    data.setTemperature(new BigDecimal(item.get("tempture").asText()));
                    break;
                case 4:  // 血糖
                    data.setBloodGlucose(new BigDecimal(item.get("bloodGlucose").asText()));
                    break;
            }
            return data;
        } catch (Exception e) {
            return null;
        }
    }

    private boolean isDataExists(UserHealthData data, int dataType) {
        Integer count = dataMapper.exists( // 使用包装类型接收
                data.getUserId(),
                data.getTime(),
                TYPE_MAPPING.get(dataType)
        );
        return count != null && count > 0;
    }
}